﻿using System;
using System.Collections.Generic;
using System.Web.Http;
using SalesSys.Comm.BLL;
using SalesSys.Comm.Utility;
using SalesSys.DAL.Models;
using SalesSys.Service.Sales;
using SalesSys.Site.Models;
using SalesSys.WebCore;
using SalesSys.WebCore.Authorize;
using SalesSys.BLL;
using SalesSys.BLL.Sales;
using System.Net.Http;
using System.IO;
using hlib.IO;
using System.Linq;
using System.Transactions;
using SalesSys.Site.Models.Phone;
using SalesSys.Service.Purchasing;
using System.Text;
using System.Net;

namespace SalesSys.Site.Controllers.Api
{
    /// <summary>
    /// 手机端接口
    /// </summary>
    [RoutePrefix("api/Phone")]
    public class PhoneController : ApiController
    {
        OrderBLL orderBLL = BllFactory.GetBll<OrderBLL>();
        ProviderBLL providerBLL = BllFactory.GetBll<ProviderBLL>();
        EmployeeBLL employeeBLL = BllFactory.GetBll<EmployeeBLL>();
        DepotCommodityBLL dcBLL = BllFactory.GetBll<DepotCommodityBLL>();//仓库商品
        CustomerBalanceBLL customerBalanceBLL = new CustomerBalanceBLL();//账户金额
        LockOrderBLL lockBLL = BllFactory.GetBll<LockOrderBLL>();
        CustomerBLL customerBLL = BllFactory.GetBll<CustomerBLL>();
        AccountBLL accountBLL = BllFactory.GetBll<AccountBLL>();
        DistrictBLL districtBLL = BllFactory.GetBll<DistrictBLL>();
        DepotCommodityRecordBLL depotCommodityRecordBLL = BllFactory.GetBll<DepotCommodityRecordBLL>();
        CommodityBLL commodityBLL = BllFactory.GetBll<CommodityBLL>();
        CommodityInfoBLL commodityInfoBLL = BllFactory.GetBll<CommodityInfoBLL>();
        IDirectSale saleSvc = new SalesSvc();
        IPurchasingSvc purchasingSvc = new PurchasingSvc();
        IBaseBLL<PurchaseOrder, Guid> purchaseOrderBll = new PurchasingSvc();
        PhoneLogBLL phoneLogBll = BllFactory.GetBll<PhoneLogBLL>();

        #region 通用方法
        /// <summary>
        /// 判断每个页面是否处于登陆状态，如果不是，则跳转到登陆界面
        /// </summary>
        /// <returns></returns>
        public bool IfLogin(string token)
        {
            if (!string.IsNullOrEmpty(token))
            {
                return true;
            }
            return false;
        }
        #endregion

        #region User 用户管理

        /// <summary>
        /// 登录接口
        /// </summary>
        /// <param name="loginName">登录手机号</param>
        /// <param name="LoginPwd">登录密码</param>
        /// <returns></returns>
        [Route("User/Login")]
        public IResultState Login(string loginName, string LoginPwd)
        {
            var emp = employeeBLL.CheckPw(loginName, LoginPwd);
            if (emp == null)
            {
                emp = employeeBLL.GetUserByJudge(loginName);
                if (emp == null)
                    return ReState.Error.Create("登录失败，该用户不存在");
                else if (emp.LoginPwd != LoginPwd)
                    return ReState.Error.Create("登录失败，密码错误");
                else if (emp.IsLeave)
                    return ReState.Error.Create("登录失败，您已离职");
                else
                    return ReState.Error.Create("登录失败，用户名和密码错误");
            }
            emp.Token = System.Guid.NewGuid().ToString("N");
            employeeBLL.Edit(emp);
            var empDto = new EmployeeDto();
            empDto.ToEntity(emp);
            return ReState.Success.CreateResult("登录成功", empDto);
        }

        /// <summary>
        /// 发送验证码
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <param name="phone">手机号</param>
        /// <returns></returns>
        [Route("User/SendVerification")]
        public IResultState SendVerification(string token, string phone)
        {
            //验证用户是否存在
            var emp = employeeBLL.GetUserByJudge(token);
            if (emp == null)
                return ReState.Error.Create("该用户不存在");
            //调用发送接口进行验证码发送
            phoneLogBll.SendMsg(CreateValidateCode(4), token, phone);
            return ReState.Success.Create("成功发送验证码");
        }

        /// <summary>  
        /// 生成验证码  
        /// </summary>  
        /// <param name="length">指定验证码的长度</param>  
        /// <returns></returns>  
        public string CreateValidateCode(int length)
        {
            int[] randMembers = new int[length];
            int[] validateNums = new int[length];
            string validateNumberStr = "";
            //生成起始序列值  
            int seekSeek = unchecked((int)DateTime.Now.Ticks);
            Random seekRand = new Random(seekSeek);
            int beginSeek = (int)seekRand.Next(0, Int32.MaxValue - length * 10000);
            int[] seeks = new int[length];
            for (int i = 0; i < length; i++)
            {
                beginSeek += 10000;
                seeks[i] = beginSeek;
            }
            //生成随机数字  
            for (int i = 0; i < length; i++)
            {
                Random rand = new Random(seeks[i]);
                int pownum = 1 * (int)Math.Pow(10, length);
                randMembers[i] = rand.Next(pownum, Int32.MaxValue);
            }
            //抽取随机数字  
            for (int i = 0; i < length; i++)
            {
                string numStr = randMembers[i].ToString();
                int numLength = numStr.Length;
                Random rand = new Random();
                int numPosition = rand.Next(0, numLength - 1);
                validateNums[i] = Int32.Parse(numStr.Substring(numPosition, 1));
            }
            //生成验证码  
            for (int i = 0; i < length; i++)
            {
                validateNumberStr += validateNums[i].ToString();
            }
            return validateNumberStr;
        }

        /// <summary>
        /// 修改手机号
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <param name="pwd">密码</param>
        /// <param name="phone">手机号</param>
        /// <param name="verCode">验证码</param>
        /// <returns></returns>
        [Route("User/UpdatePhone")]
        public IResultState UpdatePhone(string token, string pwd, string phone, string verCode)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //非空校验
            if (string.IsNullOrEmpty(phone))
            {
                return ReState.Error.Create("请输入手机号");
            }
            //验证用户密码
            var emp = employeeBLL.CheckPw(token, pwd);
            if (emp == null)
            {
                return ReState.Error.Create("该用户已经失效，请联系你的管理员");
            }
            //验证验证码
            var phoneLog = phoneLogBll.GetLastTimeSendMsg(token, phone);
            if (phoneLog != null)
            {
                if (DateTime.Now >= phoneLog.OperaTime.AddMinutes(10))
                {
                    return ReState.Error.Create("验证码已失效，请重新输入");
                }
                else
                {
                    if (token == phoneLog.OperaMessage)
                    {
                        //更新手机号
                        emp = employeeBLL.Details(emp.Id);
                        emp.Phone = phone;
                        employeeBLL.Edit(emp);
                        return ReState.Success.Create("修改成功");
                    }
                    else
                    {
                        return ReState.Success.Create("验证码输入错误，请重新输入");
                    }
                }
            }
            else
            {
                return ReState.Error.Create("未找到相关的验证码信息，请重新输入");
            }
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <param name="pwd">密码</param>
        /// <param name="phone">手机号</param>
        /// <param name="verCode">验证码</param>
        /// <returns></returns>
        [Route("User/UpdatePassword")]
        public IResultState UpdatePassword(string token, string pwd, string newPwd, string phone, string verCode)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //非空校验
            if (string.IsNullOrEmpty(phone))
            {
                return ReState.Error.Create("请输入手机号");
            }
            if (string.IsNullOrEmpty(pwd))
            {
                return ReState.Error.Create("请输入原密码");
            }
            if (string.IsNullOrEmpty(newPwd))
            {
                return ReState.Error.Create("请输入新密码");
            }
            //验证用户名密码
            var emp = employeeBLL.CheckPw(token, pwd);
            if (emp == null)
            {
                return ReState.Error.Create("该用户已经失效，请联系你的管理员");
            }
            var phoneLog = phoneLogBll.GetLastTimeSendMsg(token, phone);
            if (phoneLog != null)
            {
                if (DateTime.Now >= phoneLog.OperaTime.AddMinutes(10))
                {
                    return ReState.Error.Create("验证码已失效，请重新输入");
                }
                else
                {
                    if (token == phoneLog.OperaMessage)
                    {
                        //更新密码
                        emp = employeeBLL.Details(emp.Id);
                        emp.LoginPwd = newPwd;
                        employeeBLL.Edit(emp);
                        return ReState.Success.Create("修改成功");
                    }
                    else
                    {
                        return ReState.Success.Create("验证码输入错误，请重新输入");
                    }
                }
            }
            else
            {
                return ReState.Error.Create("未找到相关的验证码信息，请重新输入");
            }
        }

        /// <summary>
        /// 登出接口
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <returns></returns>
        [Route("User/Logout")]
        public IResultState Logout(string token)
        {
            var employeeBLL = BllFactory.GetBll<EmployeeBLL>();
            var emp = employeeBLL.GetUserByToken(token);
            emp.Token = "";
            employeeBLL.Edit(emp);
            return ReState.Success.Create("登出成功");
        }

        /// <summary>
        /// 登录后首页数据
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <returns></returns>
        [Route("User/Index")]
        public IResultState User_Index(string token)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            var indexDto = new IndexDto();
            //返回今日库存量、今日销量、今日销售额
            //我发起的审批数量、带我确认的审批数
            //系统消息列表，top10条
            return ReState.Success.CreateResult("获取成功", indexDto);
        }
        #endregion

        #region Provider 供应商

        /// <summary>
        /// 添加供应商（仓库、钢厂、贸易商）
        /// </summary>
        /// <param name="providerDto">供应商实体</param>
        /// <returns></returns>
        [Route("Provider/Add")]
        public IResultState Provider_Add(string token, ProviderDto providerDto)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //验证权限
            var old = providerBLL.GetList(p => p.Name == providerDto.Name);
            if (old.Length > 0)
            {
                return ReState.Error.Create("重复的名称");
            }
            var provider = providerDto.ToEntity();
            provider.DepotCommoditys = null;
            provider.Supplier = null;

            if (provider.OperationsMan != null)
            {
                provider.OperationsMan = employeeBLL.Details(provider.OperationsMan.Id);
            }
            if (provider.Manager != null)
            {
                provider.Manager = employeeBLL.Details(provider.Manager.Id);
            }
            else
            {
                return ReState.Error.Create("请选择区域经理");
            }
            if (provider.MainFieldMan != null)
            {
                provider.MainFieldMan = employeeBLL.Details(provider.MainFieldMan.Id);
            }
            else
            {
                return ReState.Error.Create("请选择驻厂专员");
            }
            provider.District = BllFactory.GetBll<DistrictBLL>().Details(provider.District.Id);
            if (provider.District == null)
            {
                return ReState.Error.Create("仓库所在地错误");
            }
            providerBLL.Create(provider);
            return ReState.Success.CreateResult("添加成功", provider);
        }


        /// <summary>
        /// 供应商列表
        /// </summary>
        /// <param name="type">供应商类型</param>
        /// <param name="name">名称,模糊查询</param>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <returns></returns>
        [Route("Provider/List")]
        public IResultState Provider_List(string token, ProviderType? type = null, string name = null, int page = 1, int rows = 10)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //验证权限
            ViewDtos<Provider> dto = null;
            var re = providerBLL.QueryProviders(type, name, page, rows);
            dto = ViewDto.CreateList(re.Value);
            dto.Total = re.Key;
            dto.Rows = rows;
            dto.Page = page;
            return ReState.Success.CreateResult("获取成功", dto);
        }

        /// <summary>
        /// 供应商详情
        /// </summary>
        /// <param name="providerId">供应商编号</param>
        /// <returns></returns>
        [Route("Provider/List")]
        public IResultState Provider_List(string token, Guid providerId)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //验证权限
            var provider = providerBLL.Details(providerId);
            return ReState.Success.CreateResult("获取成功", provider);
        }


        /// <summary>
        /// 获取供应商商品
        /// </summary>
        /// <param name="depotId">供应商编号</param>
        /// <param name="name">商品名称</param>
        /// <param name="keyStr">品牌名称</param>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <returns></returns>
        [Route("Provider/DepotCommodity")]
        public IResultState GetDepotCommodity(string token, Guid? depotId, string name = null, string keyStr = null, int page = 1, int rows = 10)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //验证权限
            var dcs = dcBLL.GetDepotCommodityList(depotId, name, keyStr, page, rows).Value;
            return ReState.Success.CreateResult("获取成功", dcs);
        }

        /// <summary>
        /// 批量修改供应商商品
        /// </summary>
        /// <param name="depotCommoditys">供应商商品</param>
        [Route("Provider/EditProviderCommodity")]
        public IResultState EditProviderCommodity(string token, DepotCommodity[] depotCommoditys)
        {
            if (!IfLogin(token))
            {
                return ReState.Error.CreateResult("登陆已失效，请重新登陆", false);
            }
            //验证权限
            var list = new List<DepotCommodity>();
            foreach (var item in depotCommoditys)
            {
                var old = dcBLL.Details(item.ProviderId, item.CommodityId);
                old.Amount = item.Amount;
                //old.Price = item.Price;
                old.MinAmount = item.MinAmount;
                old.UpdateTime = DateTime.Now;
                list.Add(old);
            }
            foreach (var item in list)
            {
                dcBLL.Edit(item);
            }
            return ReState.Success.Create("修改成功");
        }


        #endregion

        #region Order 计划单

        /// <summary>
        /// 获取计划单
        /// </summary>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <param name="state">订单状态</param>
        /// <param name="type">订单类型</param>
        /// <param name="name">供应商名称\客户名称\客户简称</param>
        /// <returns></returns>
        [Route("Order/List")]
        public IResultState Order_List(string token, int page, int rows, OrderState? state, OrderType? type, string name = null, DateTime? startTime = null, DateTime? endTime = null)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            //根据登录角色判断读取计划单类型（客户经理、驻厂）
            //orderBLL.OrderList(keyword, emp.Id, null, state, startTime, endTime, page, rows);
            var re = orderBLL.GetFieldManOrder(emp.Id, page, rows, state, type, name);
            var dto = new ViewDtos<Order>();
            dto.Data = re.Value;
            dto.Total = re.Key;
            dto.Page = page;
            dto.Rows = rows;
            return ReState.Success.CreateResult("获取成功", dto);
        }

        /// <summary>
        /// 计划单详情
        /// </summary>
        /// <param name="id">订单编号</param>
        [Route("Order/Detail")]
        public IResultState Order_Detail(string token, Guid orderId)
        {
            //验证权限
            var result = orderBLL.Details(orderId);
            //查询当前账户当前客户经理当前客户的余额
            if (result != null)
            {
                result.Account.Amount = customerBalanceBLL.GetAccountAmount(result.Customer.Id, result.Creater.Id, result.Account.Id);
            }
            return ReState.Success.CreateResult("获取成功", result);
        }

        /// <summary>
        /// 创建计划单
        /// </summary>
        /// <param name="model">计划单实体类</param>
        [Route("Order/Add")]
        public IResultState Order_Add(string token, OrderDto model)
        {
            var emp = employeeBLL.GetUserByToken(token);
            //验证权限
            using (var tran = new TransactionScope())
            {
                var order = model.ToEntity();
                order.Creater = employeeBLL.Details(emp.Id);
                order.Customer = customerBLL.Details(model.CustomerId);
                order.Provider = providerBLL.Details(model.ProviderId);
                order.Account = accountBLL.Details(model.AccountId);
                order.District = districtBLL.Details(model.DistrictId);
                //运费户头
                if (order.IsPublicDelivery)
                    order.DeliveryAccount = order.Account;
                else
                    order.DeliveryAccount = accountBLL.GetCashAccountByCustomerId(order.Customer.Id);
                if (order.DeliveryAccount == null)
                {
                    return ReState.ArgError.Create("不能找到指定的运费户头");
                }
                if (model.LockOrderId != Guid.Empty)
                    order.LockOrder = lockBLL.Details(model.LockOrderId);
                order.IsStandard = !order.Account.IsCash;
                order.CommodityInfos = new List<CommodityInfo>();
                foreach (var item in model.CommodityInfos)
                {
                    var commodityInfo = new CommodityInfo();
                    item.ToEntity(commodityInfo);
                    if (commodityInfo.Price == 0)
                        return ReState.ArgError.Create("商品价格不能为0");
                    commodityInfo.Commodity = commodityBLL.Details(item.CommodityId);
                    commodityInfo.Price = commodityInfo.Price;
                    commodityInfo.Weight = commodityInfo.Commodity.Weight;
                    commodityInfo.CalcNew();
                    order.CommodityInfos.Add(commodityInfo);
                }

                //先行判断该客户在余额表中是否存在
                if (!customerBalanceBLL.IsExistAccount(model.CustomerId, ClientHelper.ClientInfo.Id))
                {
                    //判断该客户下有多少个户头
                    Customer customer = customerBLL.Details(model.CustomerId);
                    if (customer != null)
                    {
                        foreach (var item in customer.Accounts)
                        {
                            //添加账户余额
                            CustomerBalance customerBalance = new CustomerBalance();
                            customerBalance.EmployeeId = ClientHelper.ClientInfo.Id;
                            customerBalance.CustomerId = model.CustomerId;
                            customerBalance.AccountId = item.Id;
                            customerBalance.Id = Guid.NewGuid();
                            customerBalance.Balance = 0;
                            customerBalanceBLL.Create(customerBalance);

                        }
                    }
                }
                var result = saleSvc.Create(order);
                tran.Complete();
                return result;
            }
        }

        /// <summary>
        /// 取消计划单
        /// </summary>
        /// <param name="id">取消计划单</param>
        [Route("Order/Cancel")]
        public IResultState Order_Cancel(string token, Guid orderId)
        {
            var emp = employeeBLL.GetUserByToken(token);
            //验证权限
            var order = orderBLL.Details(orderId);
            if (order.State == OrderState.Pending || order.State == OrderState.Checked)
            {
                saleSvc.Cancel(orderId, emp.Id);
            }
            else if (order.State == OrderState.Cancel || order.State == OrderState.Return ||
                     order.State == OrderState.End)
            {
                return ReState.ArgError.Create("错误的订单状态");
            }
            else
            {
                order.IsApproval = true;
                order.Records.Add(new OrderRecord { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, LinkId = emp.Id.ToString(), Remarks = "[" + emp.Name + "] 提交计划单取消操作，等待审核人[" + order.Provider.Manager.Name + "]审批。" });
                saleSvc.Edit(order);
                //取消审批
                SequenceApprovalBLL.CancelOrderApproval cancelOrderBll = new SequenceApprovalBLL.CancelOrderApproval();
                cancelOrderBll.Submit(order);//取消审批
            }
            return ResultState.CreateSuccess();
        }

        /// <summary>
        /// 驻厂确认订单
        /// </summary>
        /// <param name="orderId">计划单编号</param>
        /// <returns></returns>
        [Route("Order/Confirm")]
        public IResultState Order_Confirm(string token, Guid orderId)
        {
            //验证权限
            //判断订单类型（库提、厂提）厂提：生成采购单
            //修改订单状态为已确认
            return ResultState.CreateSuccess();
        }

        /// <summary>
        /// 确认发货
        /// </summary>
        /// <param name="orderId">计划单编号</param>
        /// <returns></returns>
        [Route("Order/ConfirmSend")]
        public IResultState Order_ConfirmSend(string token, Guid orderId)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            var order = orderBLL.Details(orderId);
            if (order.State != OrderState.Ordered)
            {
                return ReState.ArgError.Create("订单状态无效");
            }
            var state = saleSvc.OrderSend(emp.Id, orderId);
            if (state.State == (int)ReState.Success)
            {
                var str = string.Format("{0:M/d HH:mm} 驻厂人员[{1}]已经成功发货", DateTime.Now, order.Provider.MainFieldMan.Name);
                // SendMsg(str, order.Creater.Id); todo..消息发送统一处理
            }
            return state;
        }

        /// <summary>
        /// 追加发货信息,并出库
        /// </summary>
        /// <param name="token">唯一标识</param>
        /// <param name="ord">计划单实体</param>
        /// <returns></returns>
        [Route("Order/EditSendInfo")]
        public IResultState Order_EditSendInfo(string token, Order ord)
        {
            //验证权限
            //判断订单类型（库提、厂提）
            return ResultState.CreateSuccess();
        }


        /// <summary>
        /// 基本信息修改，不允许修改：客户、仓库、省市，户头
        /// </summary>
        /// <param name="orderDto">计划单模型类</param>
        /// <returns></returns>
        [Route("Order/BaseEdit")]
        public IResultState Order_BaseEdit(string token, OrderDto orderDto)
        {
            var old = orderBLL.Details(orderDto.Id);
            var msg = "";
            if (old.Address != orderDto.Address)
                msg = "[地址信息]";
            else if (old.VehicleInfos != orderDto.VehicleInfos)
                msg = "[车辆信息]";
            var order = orderDto.ToEntity(old);
            OrderBLL.SetOrderChangeRecord(order, DiscountType.BaseInfo, ClientHelper.ClientInfo, 0, null, msg);
            saleSvc.Edit(order);
            return ResultState.CreateSuccess();
        }

        /// <summary>
        /// 编辑商品，如果商品重量为0，则从订单中删除
        /// </summary>
        /// <param name="ord">计划单实体</param>
        /// <returns></returns>
        [Route("CommodityInfoEdit")]
        public IResultState CommodityInfoEdit(string token, Order ord)
        {
            //权限验证
            var cmmdInfoDtos = ord.CommodityInfos;
            using (var tran = new TransactionScope())
            {
                var ciBll = BllFactory.GetBll<BaseBLL<CommodityInfo, Guid>>();
                var commBll = BllFactory.GetBll<BaseBLL<Commodity, Guid>>();
                var order = orderBLL.Details(ord.Id);
                var oldTotal = order.Total;
                saleSvc.CommodityInfoEdit(ord, ClientHelper.ClientInfo);
                order.CalcNew();
                saleSvc.Edit(order);
                if (order.IsSettlement)
                {
                    saleSvc.Settlement(ClientHelper.ClientInfo.Id, order.Id);
                }
                tran.Complete();
            }
            return ResultState.CreateSuccess();
        }

        #endregion

        #region LockOrder 锁价单

        /// <summary>
        /// 我的锁价单列表
        /// </summary>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <param name="state">状态</param>
        /// <param name="keyword">模糊查询</param>
        [Route("LockOrder/List")]
        public IResultState LockOrder_List(string token, int page, int rows, OrderState? state = null, string keyword = null)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            var bll = BllFactory.GetBll<LockOrderBLL>();
            var re = bll.Select(emp.Id, keyword, state, new QueryInfo { Page = page, Rows = rows });
            var dto = new ViewDto<IEnumerable<LockOrder>>();
            dto.Data = re.Value;
            dto.Total = re.Key;
            dto.Page = page;
            dto.Rows = rows;
            return ReState.Success.CreateResult("获取成功", dto);
        }
        /// <summary>
        /// 锁价单详情
        /// </summary>
        /// <param name="id">锁价单编号</param>
        [Route("LockOrder/Detail")]
        public IResultState LockOrder_Detail(string token, Guid id)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            var result = lockBLL.Details(id);
            return ReState.Success.CreateResult("获取成功", result);
        }

        /// <summary>
        /// 创建锁价单
        /// </summary>
        /// <param name="model">锁价单实体类</param>
        [Route("LockOrder/Add")]
        public IResultState LockOrder_Add(string token, LockOrderDto model)
        {
            try
            {
                //验证权限
                var emp = employeeBLL.GetUserByToken(token);
                using (var tran = new TransactionScope())
                {
                    PaymentInfoBLL paymentInfoBLL = new PaymentInfoBLL();
                    var order = model.ToEntity();
                    order.Creater = employeeBLL.Details(emp.Id);
                    order.Customer = customerBLL.Details(model.CustomerId);
                    if (paymentInfoBLL.CheckExecuting(model.AccountId, order.Customer.Id, order.Creater.Id, PaymentStatus.Refund))
                        return ReState.Error.Create("该账户正在退款审批中，不允许创建锁价单");

                    order.Account = accountBLL.Details(model.AccountId);
                    //其他信息
                    order.CreateTime = DateTime.Now;
                    order.OrderType = OrderType.Normal;
                    order.State = OrderState.Pending;
                    order.Provider = providerBLL.Details(model.ProviderId);
                    //判断是否是商品锁价
                    if (order.IsGoodsLock)
                    {
                        order.OrderType = OrderType.ProductLock;
                        order.DepotCommodityRecords = new List<DepotCommodityRecord>();
                        //查询仓库商品，然后转为历史价格记录
                        var dcmmdBll = new DepotCommodityBLL();
                        var comodityRecordId = Guid.Parse(model.depotCommodityRecordId.ToString());
                        var tmpInfo = dcmmdBll.GetDepotCommodity(model.ProviderId, comodityRecordId);
                        var newRecord = DepotCommodityRecord.ToDepotCommodityRecord(tmpInfo);

                        order.DepotCommodityRecords.Add(newRecord);
                    }
                    else
                    {
                        order.OrderType = OrderType.BasePriceLock;
                        //查询所有锁价商品列表
                        order.DepotCommodityRecords = depotCommodityRecordBLL.ReacordByNowDepotInfo(model.ProviderId);
                    }
                    order.IsStandard = !order.Account.IsCash;
                    //订单历史记录
                    order.Records = new List<OrderRecord>();
                    order.Records.Add(new OrderRecord() { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, Remarks = "锁价单创建" });
                    order.ProcessState = ProcessState.LockPrice;
                    order.IsApproval = true;
                    order.IsPause = false;
                    order.CalcUnitDiscount();
                    if (order.Provider.Manager != null)
                        order.Records.Add(new OrderRecord() { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, Remarks = "等待[" + order.Provider.Manager.Name + "]锁价审批" });
                    lockBLL.Create(order);

                    //提交锁价审批流程  
                    SequenceApprovalBLL.LockPriceOrderApproval approvalBll = new SequenceApprovalBLL.LockPriceOrderApproval();
                    approvalBll.Submit(order);


                    //先行判断该客户在余额表中是否存在
                    if (!customerBalanceBLL.IsExistAccount(model.CustomerId, emp.Id))
                    {
                        //判断该客户下有多少个户头
                        Customer customer = customerBLL.Details(model.CustomerId);
                        if (customer != null)
                        {
                            foreach (var item in customer.Accounts)
                            {
                                //添加账户余额
                                CustomerBalance customerBalance = new CustomerBalance();
                                customerBalance.EmployeeId = emp.Id;
                                customerBalance.CustomerId = model.CustomerId;
                                customerBalance.AccountId = item.Id;
                                customerBalance.Id = Guid.NewGuid();
                                customerBalance.Balance = 0;
                                customerBalanceBLL.Create(customerBalance);
                            }
                        }
                    }
                    tran.Complete();
                    return ReState.Success.Create("保存成功");
                }
            }
            catch (Exception ex)
            {
                return ReState.ArgError.Create(ex.Message);
            }
        }

        /// <summary>
        /// 取消锁价单
        /// </summary>
        /// <param name="lockOrderId">锁价单编号</param>
        [Route("LockOrder/Cancel")]
        public IResultState LockOrder_Cancel(string token, Guid lockOrderId)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            var order = lockBLL.Details(lockOrderId);
            if (order.State == OrderState.Pending)
            {
                lockBLL.Cancel(emp, lockOrderId);
                return ReState.Success.Create("取消锁价单成功");
            }
            else
            {
                order.IsApproval = true;
                order.Records.Add(new OrderRecord { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, LinkId = emp.Id.ToString(), Remarks = "[" + emp.Name + "] 提交锁价单取消操作" });
                if (order.Provider.Manager != null)
                    order.Records.Add(new OrderRecord() { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, Remarks = "等待[" + order.Provider.Manager.Name + "]锁价单取消审批" });
                lockBLL.Edit(order);

                //取消审批
                SequenceApprovalBLL.LockOrderRefundApproval cancelOrderBll = new SequenceApprovalBLL.LockOrderRefundApproval();
                cancelOrderBll.Submit(order, order.Total);//取消审批
                return ReState.Success.Create("进入取消锁价单审批流程");
            }
        }

        ///<summary>
        ///创建计划单
        ///</summary>
        ///<param name="lockOrderId">锁价单编号</param>
        [Route("LockOrder/AddOrder")]
        public IResultState AddOrder(string token, Guid lockOrderId)
        {
            var order = new Order();
            try
            {
                //验证权限
                var emp = employeeBLL.GetUserByToken(token);
                var lockOrder = lockBLL.Details(lockOrderId);
                order.Creater = employeeBLL.Details(emp.Id);
                order.Customer = customerBLL.Details(lockOrder.Customer.Id);
                order.Account = accountBLL.Details(lockOrder.Account.Id);
                order.IsFullPayment = true;
                order.IsStandard = order.IsStandard;
                order.OrderType = lockOrder.OrderType;
                //其他信息
                order.Provider = lockOrder.Provider;
                order.Provider.Id = lockOrder.Provider.Id;
                order.Provider.Name = lockOrder.Provider.Name;
                order.OrderType = lockOrder.OrderType;
                order.ApplyDiscount = lockOrder.ApplyDiscount;

                //仓库历史记录转仓库商品编号
                var infoList = new List<DepotCommodity>();
                //查找实时库存
                var dcmmdBll = new DepotCommodityBLL();
                foreach (var item in lockOrder.DepotCommodityRecords)
                {
                    var depotCommodity = new DepotCommodity();
                    depotCommodity.CommodityId = item.Commodity.Id;
                    depotCommodity.Commodity = item.Commodity;
                    var dm = dcmmdBll.GetDepotCommodity(item.Provider.Id, item.Commodity.Id);
                    depotCommodity.Amount = dm != null ? dm.Amount : 0;
                    depotCommodity.Price = item.Price;
                    depotCommodity.Provider = item.Provider;
                    infoList.Add(depotCommodity);
                }
                //订单历史记录
                order.Records = new List<OrderRecord>();
                return ReState.Success.CreateResult("进入取消锁价单审批流程", new { Order = order, DepotCommodity = infoList, Surplus = lockOrder.GetSurplus() });
            }
            catch (Exception ex)
            {
                return ReState.Error.Create("创建失败");
            }
        }

        /// <summary>
        /// 退款锁价单
        /// </summary>
        /// <param name="lockOrderId">锁价单编号</param>
        [Route("Refund")]
        public IResultState Refund(string token, Guid lockOrderId)
        {
            //验证权限
            var emp = employeeBLL.GetUserByToken(token);
            var order = lockBLL.Details(lockOrderId);
            if (order.State == OrderState.Pending)
            {
                return ReState.Error.Create("未确认订单不允许退款");
            }
            else if (order.IsApproval)
            {
                return ReState.Error.Create("审批中订单不允许退款");
            }
            else
            {
                decimal money = 0.0M;
                money =
                    order.Orders.Where(
                        p =>
                            p.State != OrderState.Cancel && p.State != OrderState.Refund && p.State != OrderState.Return)
                        .Sum(p => p.Total);
                money = order.Total - money;
                if (order.State == OrderState.Refund)
                {
                    if (money <= order.Refund)
                        return ReState.Error.Create("该计划单已退款");
                    else
                        money = money - order.Refund;
                }
                if (money <= 0)
                    return ReState.Error.Create("该计划单无余款可退");
                order.IsApproval = true;
                //order.State = OrderState.Pending;
                order.Records.Add(new OrderRecord { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, LinkId = emp.Id.ToString(), Remarks = "[" + emp.Name + "] 提交锁价单退款操作" });
                if (order.Provider.Manager != null)
                    order.Records.Add(new OrderRecord() { CreateTime = DateTime.Now, DiscountType = DiscountType.Msg, Remarks = "等待[" + order.Provider.Manager.Name + "]锁价单退款审批" });
                lockBLL.Edit(order);
                //退款审批
                SequenceApprovalBLL.LockOrderRefundApproval refundOrderBll = new SequenceApprovalBLL.LockOrderRefundApproval();
                refundOrderBll.Submit(order, money);//退款审批
                return ReState.Success.Create("进入退款锁价单审批流程");
            }
        }
        #endregion

        #region Purchase 采购单

        /// <summary>
        /// 获取采购单列表
        /// </summary>
        /// <param name="name">联系人\创建人名称\供应商名称，模糊查询</param>
        /// <param name="state">采购单状态</param>
        /// <param name="page">分页</param>
        /// <param name="rows">每页条数</param>
        /// <returns></returns>
        [Route("Purchasing/List")]
        public IResultState Purchase_List(string token, string name = null, PurchaseOrder.PurchaseState? state = null, int page = 1, int rows = 10)
        {
            //权限验证
            var data = purchasingSvc.GetList(name, state, ClientHelper.ClientInfo.Id, page, rows);
            var dto = ViewDto.CreateList(data.Value);
            dto.Total = data.Key;
            dto.Page = page;
            dto.Rows = rows;
            return ReState.Success.CreateResult("获取成功", dto);
        }

        /// <summary>
        /// 创建采购单并提交
        /// </summary>
        /// <param name="purchaseOrder">采购单实体</param>
        /// <returns></returns>
        [Route("Purchasing/Create")]
        public IResultState Purchase_Create(string token, PurchaseOrder purchaseOrder)
        {
            //权限验证
            if (purchaseOrder.Provider == null || purchaseOrder.Provider.ProviderType == ProviderType.Depot)
            {
                return ReState.ArgError.Create("错误的供应商信息");
            }
            if (purchaseOrder.Goodses == null || purchaseOrder.Goodses.Count < 1)
            {
                return ReState.ArgError.Create("商品信息错误");
            }
            if (purchaseOrder.Provider.Manager == null || purchaseOrder.Provider.MainFieldMan == null)
            {
                return ReState.ArgError.Create("供应商驻厂专员或区域经理未配置，请联系管理员");
            }


            purchaseOrder.Creater = employeeBLL.Details(ClientHelper.ClientInfo.Id);
            purchaseOrder.PurchaseType = PurchaseType.Creater;
            return purchasingSvc.Create(purchaseOrder);
        }

        /// <summary>
        /// 采购单入库
        /// </summary>
        /// <param name="purchaseOrderId">采购单编号</param>
        /// <returns></returns>
        [Route("Purchasing/Entry")]
        public IResultState Purchasing_Entry(string token, Guid purchaseOrderId)
        {
            //权限验证
            return purchasingSvc.PurchasingEntry(purchaseOrderId);
        }
        /// <summary>
        /// 修改采购单价格，已入库则设置入库单成本
        /// </summary>
        /// <param name="porder">采购单实体</param>
        /// <returns></returns>
        [Route("Purchasing/SetPrice")]
        public IResultState Purchasing_SetPrice(string token, PurchaseOrder porder)
        {
            //权限验证
            return purchasingSvc.SetPurchasingPrice(ClientHelper.ClientInfo.Id, porder);
        }

        /// <summary>
        /// 修改采购单价格和重量，已入库则设置入库单成本
        /// </summary>
        /// <param name="porder">采购单实体</param>
        /// <returns></returns>
        [Route("Purchasing/SetWeightAndPrice")]
        public IResultState Purchasing_SetWeightAndPrice(string token, PurchaseOrder porder)
        {
            //权限验证
            return purchasingSvc.SetWeightAndPrice(ClientHelper.ClientInfo.Id, porder);
        }

        /// <summary>
        /// 直发采购完成
        /// </summary>
        /// <param name="purchaseOrderId">采购单编号</param>
        /// <returns></returns>
        [Route("Purchasing/SaleComplete")]
        public IResultState Purchase_SaleComplete(string token, Guid purchaseOrderId)
        {
            //权限验证
            return purchasingSvc.SalePurchaseComplete(ClientHelper.ClientInfo, purchaseOrderId);
        }

        /// <summary>
        /// 直发销售采购单， 
        /// </summary>
        /// <param name="po">采购单实体</param>
        /// <returns></returns>
        [Route("Purchasing/SaleEdit")]
        public IResultState Purchasing_SaleEdit(string token, PurchaseOrder po)
        {
            //权限验证
            return purchasingSvc.SalePurchaseEdit(ClientHelper.ClientInfo.Id, po);
        }
        /// <summary>
        /// 修改采购单备注及联系人
        /// </summary>
        /// <param name="po">采购单实体</param>
        /// <returns></returns>
        [Route("Purchase/RemarkEdit")]
        public IResultState Purchase_RemarkEdit(string token, PurchaseOrder po)
        {
            var old = purchaseOrderBll.Details(po.Id);
            old.Remarks = po.Remarks;
            old.Contact = po.Contact;
            PurchaseOrder.AddPurchaseRecord(ClientHelper.ClientInfo, old, PurchaseRecordType.Msg, "修改联系人及备注");
            purchaseOrderBll.Edit(old);
            return ReState.Success.Create();
        }
        #endregion

        #region Customer 客户管理

        #endregion

        #region InfoCollection 钢厂信息收集

        #endregion

    }
}